/*
  Name: GLRagdoll.h
  Copyright:
  Author: ilija
  Date: 03.06.07 20:38
  Description: this ragdoll is for game only!
*/

#ifndef GLRAGDOL_H
#define GLRAGDOL_H


#include "GLObject.h"
#include "../core/String.h"
#include "../tinyxml/tinyxml.h"
#include "../core/mymath.h"
#include "../core/matrix4.h"

#define RD_MAXFRAMES 20

enum RagdollParts
{
    RP_Root = 0,
    RP_Pelvis,
    RP_LeftLeg1,
    RP_LeftLeg2,
    RP_LeftFoot,
    RP_RightLeg1,
    RP_RightLeg2,
    RP_RightFoot,
    RP_Torso1,
    RP_Torso2,
    RP_LeftArm1,
    RP_LeftArm2,
    RP_LeftHand,
    RP_RightArm1,
    RP_RightArm2,
    RP_RightHand,
    RP_Neck,
    RP_Head,
    RP_Count
};

class GLRagdoll;

struct RagdollFrame
{
    vector3f rot[RP_Count];
    //op
    const RagdollFrame &operator =(const RagdollFrame &frm);
};

struct RagdollAnimation
{
    RagdollAnimation();
    bool loadAnimation(const char* filename, float speed = 1.0f, GLRagdoll* doll = NULL);
    void saveAnimation(const char* filename, GLRagdoll* doll = NULL);
    void resetAnimation();
    void parseXmlNode(TiXmlElement* elem, RagdollFrame* frame, GLRagdoll* doll);
    //attr
    RagdollFrame    anim_frames[RD_MAXFRAMES];
    int     	    anim_frames_count;
    float           anim_speed;
};


//evo klase...
class GLRagdoll : public GLObject
{
public:
    //c/d
    GLRagdoll(GLObject* obj);

    //global
	virtual void onRender() { }
	virtual void onUpdate(float dt) { updateAnim(dt); }

    //animation
    void calcFrame(float ff);
    bool updateAnim(float dt, bool loop = true);
    void rotatePart(int part, float x, float y, float z, bool set);
    void initPart(int part, int prev_part, vector3f offset, vector3f bsize, vector3f bcenter);
    void applyCurrentFrame();

    //load/save
    void setAnimation(RagdollAnimation* anim);
	void clearAnim();

    inline void setFrame(float ff) { curFramePos = ff; calcFrame(ff); }
    inline GLObject* getBodyPart(int part) { return bodyPart[part]; }
    inline RagdollFrame& getCurrentFrame() { return curFrame; }
    inline float getFramePosition() const  { return curFramePos; }
    static int getPartByName(const char* s);

private:
    RagdollFrame        curFrame;
    RagdollAnimation*   animation;
    float               curFramePos;
    GLObject*           bodyPart[RP_Count];
};


#endif //GLRAGDOL_H


